package uk.co.douglashoskins.weathercompare.controller;

import uk.co.douglashoskins.weathercompare.WeatherCompare;
import uk.co.douglashoskins.weathercompare.providers.BBC;
import uk.co.douglashoskins.weathercompare.providers.WUnderground;
import uk.co.douglashoskins.weathercompare.providers.WeatherCallback;
import uk.co.douglashoskins.weathercompare.providers.WeatherProvider;
import uk.co.douglashoskins.weathercompare.providers.Yahoo;
import uk.co.douglashoskins.weathercompare.providers.YrNo;
import uk.co.douglashoskins.weathercompare.ui.MainScreen;

public class WeatherController implements WeatherCallback {
	private LocationController lc;
	private WeatherProvider[] providers = {new BBC(), new Yahoo(), new WUnderground(), new YrNo()};
	private WeatherObj[] objs = new WeatherObj[4];
	private int count = 0;
	private double lat, lng;
	private MainScreen ms;
	private boolean today = true;
	private boolean halt = false;
	public WeatherController(MainScreen ms) {
		this.ms = ms;
		lc = new LocationController();
		LocationToDisplay ltd = lc.getLastLocation();
		ms.setLocation(ltd);
		ms.setToday(today);
		lat = ltd.lat;
		lng = ltd.lng;
		next();
	}
	
	public void swipeLeft() {
		if (today) {
			today = false;
			ms.setToday(today);
		}
		setAvg();
	}
	
	public void swipeRight() {
		if (!today) {
			today = true;
			ms.setToday(today);
		}
		setAvg();
	}
	
	public void getLocation() {
		halt = true;
		ms.setFindingLocation(true);
		lc.findLocation((BBC)providers[0], new Callback() {
			
			public void callback(Object o) {
				System.out.println("cb: " + o);
				if (o == null) {
					ms.locationErr();
				} else {
					ms.setLocation((LocationToDisplay) o);
					count = 0;
					halt = false;
					next();
				}
				WeatherCompare.c.repaint();
			}
		});
	}
	
	private void next() {
		if (halt) return;
		if (count < providers.length) {
			WeatherProvider provider = providers[count++];
			provider.getWeather(lat, lng, this);
		}
	}
	
	private int getProviderIndex(WeatherProvider wp) {
		for (int i=0; i<providers.length; i++) {
			if (wp == providers[i]) return i;
		}
		return -1;
	}
	
	private void setAvg() {
		int actualCount = 0;
		int highs = 0, lows = 0;
		for (int i=0; i<objs.length; i++) {
			WeatherObj wo = objs[i];
			if (wo != null) {
				actualCount++;
				if (today) {
					highs += wo.today.high;
					lows += wo.today.low;
				} else {
					highs += wo.tomorrow.high;
					lows += wo.tomorrow.low;
				}
			}
		}

		ms.setAverages(highs/actualCount, lows/actualCount);
	}
	
	public void weatherCB(WeatherObj wo, WeatherProvider wp) {
		wo.logo = wp.logo();
		int provider = getProviderIndex(wp);
		objs[provider] = wo;
		ms.gotWeather(provider, wo);
		setAvg();
		WeatherCompare.c.repaint();
		next();
	}

	public void weatherErr(WeatherProvider wp) {
		ms.weathErr(getProviderIndex(wp));
		WeatherCompare.c.repaint();
		next();
	}
}
